<!--
 @description PopDateTimePicker
 @fileName index.vue
 @author zengqiongying
 @created 2022/10/30 14:04:30
-->
<template>
  <Popup
    v-model="popShow"
    position="bottom"
    :title="title"
    :show-cancel-button="false"
    :clear="clear"
    @confirm="handleSubmit"
    @clear="handleClear"
  >
    <van-calendar
      ref="calendar"
      class="cus-calendar-time"
      color="#05C4C3"
      :type="calendarType"
      :show-title="true"
      :poppable="false"
      :show-confirm="false"
      :row-height="50"
      :default-date="defaultDate"
      :style="{ height: '70vh' }"
      allow-same-day
      v-bind="$attrs"
      v-on="$listeners"
      @confirm="onCalendarConfirm"
      @select="onCalendarSelect"
    >
      <div slot="title" class="calendar-title">
        <van-field
          v-model="start"
          left-icon="calendar-o"
          class="cus-field"
          label=""
          readonly
          :placeholder="`${calendarType === 'range' ? '开始' : '日期'}${showTime?'时间':'日期'}`"
          @click.native="handleClickTime('start')"
        />
        <template v-if="calendarType === 'range'">
          <div class="separator" />
          <van-field
            v-model="end"
            left-icon="calendar-o"
            class="cus-field"
            label=""
            readonly
            placeholder="结束日期"
            @click.native="handleClickTime('end')"
          />
        </template>
        <!-- <div v-show="startDate" class="btn-clear-date" @click.stop="handleClearDate">清除日期</div> -->
      </div>
    </van-calendar>
    <van-popup v-if="showPicker" v-model="showPicker" round position="bottom" @opened="handlePopupOpen">
      <van-picker
        ref="picker"
        show-toolbar
        :columns="columns"
        swipe-duration="500"
        visible-item-count="5"
        @cancel="showPicker = false"
        @change="onPickerChange"
      >
        <div class="picker-title">
          <span>{{ pickerText }}(时分秒)</span>
          <span class="btn-confirm" @click="handleTimeconfirm">确定</span>
        </div>
      </van-picker>
    </van-popup>
  </Popup>
</template>

<script>
import Popup from '@/components/Popup'
import moment from 'moment'
import columns from './columns'
function initData() {
  return {
    show: false,
    pickerText: '时间',
    isDisabled: true,
    showPicker: false,
    startDate: '',
    endDate: '',
    startTime: '',
    endTime: '',
    timeValue: '' // 时分秒临时值
  }
}
export default {
  name: 'PopDateTimePicker',
  components: { Popup },
  props: {
    value: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: ''
    },
    calendarType: {
      type: String,
      default: 'single'
    }, // 日历选择类型：single表示选择单个日期，range 表示选择日期区间,multiple表示选择多个日期(暂不支持)
    defaultValue: {
      type: [String, Array],
      default: ''
    },
    showTime: {
      type: Boolean,
      default: false
    },
    clear: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      defaultDate: null,
      columns,
      ...initData()
    }
  },
  computed: {
    popShow: {
      set(val) {
        this.$emit('input', val)
      },
      get(val) {
        return this.value
      }
    },
    start() {
      if (!this.showTime) return this.startDate
      const val = this.startDate + ' ' + this.startTime
      return val.trim()
    },
    end() {
      if (!this.showTime) return this.endDate
      const val = this.endDate + ' ' + this.endTime
      return val.trim()
    }
  },
  watch: {
    calendarType(val) {
      this.pickerText = val === 'range' ? '开始时间' : '时间'
    },
    // 初始化默认日历
    defaultValue: {
      handler(val) {
        const d = new Date()
        if (this.calendarType === 'single') {
          const d1 = val ? new Date(val) : d
          this.defaultDate = d1
          this.startDate = moment(d1).format('YYYY-MM-DD')
          const t = this.formatTime(d1)
          this.startTime = `${t.h}:${t.m}:${t.s}`
        } else if (this.calendarType === 'range') {
          if (val instanceof Array && val.length === 2) {
            const d1 = new Date(val[0])
            const d2 = new Date(val[1])
            this.defaultDate = [d1, d2]

            this.startDate = moment(d1).format('YYYY-MM-DD')
            const t1 = this.formatTime(d1)
            this.startTime = `${t1.h}:${t1.m}:${t1.s}`

            this.endDate = moment(d2).format('YYYY-MM-DD')
            const t2 = this.formatTime(d2)
            this.endTime = `${t2.h}:${t2.m}:${t2.s}`
            return
          }
          this.defaultDate = [d, d]
          this.startDate = moment(d).format('YYYY-MM-DD')
          this.endDate = moment(d).format('YYYY-MM-DD')
          this.startTime = `00:00:00`
          this.endTime = `23:59:59`
        }
        if (this.pickerText === '开始时间' || this.pickerText === '时间') {
          this.timeValue = this.startTime
        } else {
          this.timeValue = this.endTime
        }
      },
      deep: true,
      immediate: true
    },
    startDate() {
      this.isDisabled = true
    },
    endTime(val) {
      if (!val) {
        return
      }
      if (moment(this.end).isBefore(moment(this.start))) {
        this.startTime = this.endTime
      }
      this.isDisabled = false
    },
    popShow(val) {
      if (val) {
        if (this.defaultDate) {
          const date = new Date(this.defaultDate)
          this.$nextTick(() => {
            setTimeout(() => { this.$refs.calendar.scrollToDate(date) }, 1000)
          })
        }
      }
    }
  },
  created() {
    this.pickerText = this.calendarType === 'range' ? '开始时间' : '时间'
  },
  mounted() {

  },
  methods: {
    formatTime(d) {
      const h = moment(d).hour()
      const m = moment(d).minute()
      const s = moment(d).second()
      return {
        h: h < 10 ? '0' + h : h,
        m: m < 10 ? '0' + m : m,
        s: s < 10 ? '0' + s : s
      }
    },
    // 清除日历数据
    handleClearDate() {
      this.$refs.calendar.reset()
      Object.assign(this.$data, {
        pickerText: this.calendarType === 'range' ? '开始时间' : '时间',
        isDisabled: true,
        startDate: '',
        endDate: '',
        startTime: '',
        endTime: '',
        timeValue: ''
      })
    },
    handleCalendarClosed() {
      this.$refs.calendar.reset()
      Object.assign(this.$data, initData())
    },
    handlePopupOpen() {
      if (this.pickerText === '开始时间' || this.pickerText === '时间') {
        this.$refs.picker.setIndexes([8, 0, 0])
      }
      const value = this.$refs.picker.getValues()
      const str = value.join(':')
      this.timeValue = str
      if (this.pickerText === '开始时间' || this.pickerText === '时间') {
        this.startTime = str
        return
      }
      this.endTime = str
    },
    handleTimeconfirm() {
      const str = this.timeValue
      if (this.pickerText === '开始时间' || this.pickerText === '时间') {
        this.startTime = str
        this.showPicker = false
        return
      }
      this.endTime = str
      this.showPicker = false
    },
    onPickerChange(el, value) {
      const str = value.join(':')
      this.timeValue = str
    },
    onCalendarConfirm() {
      this.$emit('confirm', { startTime: this.start, endTime: this.end })
      this.show = false
    },
    onCalendarSelect(val) {
      const now = new Date()
      const h = moment(now).hour()
      const m = moment(now).minute()
      const s = moment(now).second()
      const nowTime = `${h < 10 ? '0' + h : h}:${m < 10 ? '0' + m : m}:${s < 10 ? '0' + s : s}`

      if (this.calendarType !== 'range') {
        this.endDate = ''
        this.endTime = ''
        this.startDate = moment(val).format('YYYY-MM-DD')
        this.pickerText = '时间'
        if (this.startTime === '') {
          this.startTime = nowTime
        }
        this.initTimeDefault(`${this.startDate} ${this.startTime}`)

        if (!this.showTime) return
        this.showPicker = true
        return
      }
      if (val[1]) {
        this.endDate = moment(val[1]).format('YYYY-MM-DD')
        this.pickerText = '结束时间'
        if (this.endTime === '') {
          this.endTime = nowTime
        }
        this.initTimeDefault(`${this.endDate} ${this.endTime}`)
      } else {
        if (this.end) {
          this.endDate = ''
          this.endTime = ''
        }
        this.startDate = moment(val[0]).format('YYYY-MM-DD')
        this.pickerText = '开始时间'
        if (this.startTime === '') {
          this.startTime = nowTime
        }
        this.initTimeDefault(`${this.startDate} ${this.startTime}`)
      }
      if (!this.showTime) return
      this.showPicker = true
    },
    handleClickTime(type) {
      if (!this.showTime) return
      if (type === 'end') {
        if (this.end === '') {
          return
        }
        this.pickerText = '结束时间'
        this.initTimeDefault(this.end)
      } else {
        if (this.start === '') {
          return
        }
        this.pickerText = this.calendarType === 'range' ? '开始时间' : '时间'
        this.initTimeDefault(this.start)
        this.showPicker = true
      }
    },
    // 设置时分秒默认选中值
    initTimeDefault(datetime) {
      const time = datetime || new Date()
      const h = moment(time).hour()
      const m = moment(time).minute()
      const s = moment(time).second()
      const colvalues = [
        `${h < 10 ? '0' + h : h}`,
        `${m < 10 ? '0' + m : m}`,
        `${s < 10 ? '0' + s : s}`
      ]
      columns.forEach((c, i) => {
        const index = c.values.indexOf(colvalues[i])
        this.$set(c, 'defaultIndex', index === -1 ? 0 : index)
      })
    },
    handleSubmit() {
      let dateTime = null
      const txt = this.showTime ? '时间' : '日期'
      if (this.calendarType === 'range') {
        if (this.start === '' || this.end === '') {
          this.$toast(`请选择开始${txt}和结束${txt}`)
          return
        }
        dateTime = [this.start, this.end]
      } else {
        if (this.start === '') {
          this.$toast(`请选择${this.calendarType === 'range' ? this.showTime ? '开始时间' : '开始日期' : this.showTime ? '时间' : '日期'}`)
          return
        }
        dateTime = this.start
      }
      this.$emit('change', dateTime)
      this.$emit('input', false)
    },
    handleClear() {
      this.handleClearDate()
      this.$emit('change', '')
      this.$emit('input', false)
    }
  }
}

</script>
<style lang='less' scoped>
  .cus-calendar-time.van-calendar{
    height:360px !important;
  }
  /deep/ [class*=van-hairline]::after{
    border-color: #00C8B4;
    border-width: 2px 0;
  }
  /deep/ .van-picker-column__item--selected{
    font-size: 18px;
    font-weight: bold;
  }

  .calendar-title {
    position: relative;
    width: 100%;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: space-between;
    .cus-field{
      flex: 1;
      height: 36px;
      line-height: 20px;
      background: rgba(241, 241, 242, .5);
      padding: 8px 3px;
      font-weight: normal;
    }
    .separator{
      margin: 0 5px;
      width: 10px;
      height: 1px;
      background: #B5B7C4;
      border-radius: 1px;
    }
    .btn-clear-date{
      position: absolute;
      left: 0;
      top: -20px;
      color: #101a52;
      font-size: 14px;
      line-height: 18px;
      font-weight: bold;
      z-index: 9;
    }
  }

  /deep/ .van-picker__toolbar {
    justify-content: center;
    font-weight: 500;
  }
  /deep/ .van-calendar__bottom-info{
    bottom: 4px;
  }
  .picker-title{
    width: 100%;
    position: relative;
    font-weight: bold;
    font-size: 14px;
    text-align: center;
    .btn-confirm{
      position: absolute;
      right: 10px;
      top: 0;
      z-index: 9;
      font-weight: normal;
      font-size: 12px;
      color:#009E77;
    }
  }
</style>
